<template>
  <div class="dict-select" :key="widgetId">
    <el-select
      :model-value="selectedValue"
      style="width: 100%"
      :multiple="multiple"
      :collapse-tags="collapseTags"
      :disabled="disabled"
      :size="size"
      :clearable="clearable"
      :placeholder="placeholder"
      :teleported="false"
      popper-class="data-select-popper"
      @visible-change="onVisibleChange"
      @clear="onClear"
      @remove-tag="removeItem"
      @focus="() => emit('focus')"
      @blur="() => emit('blur')"
    >
      <el-option
        v-for="item in selectedItems"
        :key="item[dialogProps.value]"
        :label="item[dialogProps.label]"
        :value="item[dialogProps.value]"
      />
    </el-select>
  </div>
</template>

<script setup lang="ts">
import { getUUID } from '@/common/utils';
import { ANY_OBJECT } from '@/types/generic';
import { Dialog } from '@/components/Dialog';
import { OnlineOperationController } from '@/api/online';
import DictSelectDlg from './dictSelectDlg.vue';

const emit = defineEmits<{
  'update:modelValue': [string | number | ANY_OBJECT[]];
  change: [
    string | number | ANY_OBJECT[],
    string | number | ANY_OBJECT[],
    ANY_OBJECT | ANY_OBJECT[],
  ];
  blur: [];
  focus: [];
}>();

const props = withDefaults(
  defineProps<{
    modelValue: string | number | Array<ANY_OBJECT> | undefined;
    size?: '' | 'default' | 'small' | 'large';
    disabled?: boolean;
    placeholder?: string;
    clearable?: boolean;
    collapseTags?: boolean;
    widget?: ANY_OBJECT;
    ignoreSelect?: boolean;
    multiple?: boolean;
  }>(),
  {
    size: 'default',
    placeholder: '请选择',
    collapseTags: true,
    multiple: false,
    disabled: false,
    clearable: true,
    ignoreSelect: false,
  },
);

const form = inject('form', () => {
  console.error('OnlineCardTable: form not injected');
  return { isEdit: false } as ANY_OBJECT;
});

const selectedItems = ref<ANY_OBJECT[]>([]);
const selectedValue = ref<string | number | ANY_OBJECT[]>();
const widgetId = ref(getUUID());

const dictInfo = computed(() => {
  let dictInfo = props.widget?.column?.dictInfo;
  let dialogSetting;
  if (dictInfo != null && typeof dictInfo.dictDataJson === 'string') {
    try {
      let dictData = JSON.parse(dictInfo.dictDataJson);
      dialogSetting = dictData.dialogSetting;
    } catch (e) {
      console.error('JSON parse error:', e);
    }
  }
  return dictInfo
    ? {
        dictId: dictInfo.dictId,
        dictName: dictInfo.dictName,
        valueColumnName: dictInfo.valueColumnName,
        keyColumnName: dictInfo.keyColumnName,
        parentKeyColumnName: dictInfo.parentKeyColumnName,
        treeFlag: dictInfo.treeFlag,
        dialogSetting: dialogSetting,
      }
    : null;
});

const formData = inject('formData', () => {
  console.error('OnlineCardTable: formData not injected');
  return {} as ANY_OBJECT;
});

const dialogProps = computed(() => {
  if (dictInfo.value == null) {
    return {
      label: 'label',
      value: 'value',
    };
  }
  return {
    label: dictInfo.value.valueColumnName,
    value: dictInfo.value.keyColumnName,
  };
});

const handlerEditOperate = selectValue => {
  if (dictInfo.value == null) return;
  if (props.multiple) {
    (selectValue || []).forEach(item => {
      if (item[dictInfo.value.keyColumnName] != null) {
        item[dictInfo.value.keyColumnName] = item[dictInfo.value.keyColumnName].toString();
      }
    });
    selectedItems.value = selectValue;
    selectedValue.value = (selectValue || []).map(item => item[dictInfo.value.keyColumnName]);
  } else {
    if (selectValue != null && selectValue[dictInfo.value.keyColumnName] != null) {
      selectValue[dictInfo.value.keyColumnName] =
        selectValue[dictInfo.value.keyColumnName].toString();
    }
    selectedItems.value = [selectValue];
    selectedValue.value = selectValue[dictInfo.value.keyColumnName];
  }
  emitChange(selectValue);
};

const removeItem = id => {
  selectedItems.value = selectedItems.value.filter(item => item[dialogProps.value.value] !== id);
  selectedValue.value = selectedItems.value.map(item => item[dialogProps.value.value]);
  emitChange(selectedItems.value);
};

const onVisibleChange = visible => {
  if (visible && !form().isEdit) {
    Dialog.show(
      '字典数据选择',
      DictSelectDlg,
      {
        area: ['1000px', '650px'],
        offset: '100px',
      },
      {
        value: selectedItems.value,
        dictInfo: dictInfo.value,
        multiple: props.multiple,
        props: dialogProps.value,
        ignoreSelect: props.widget?.props?.ignoreSelect,
        path: 'thirdDictSelect/' + widgetId.value,
      },
      {
        width: '1000px',
        height: '650px',
        pathName: '/thirdParty/thirdDictSelect',
      },
    )
      .then(res => {
        handlerEditOperate(res);
      })
      .catch(() => {
        // 取消
      });
  }
};

const onClear = () => {
  selectedItems.value = [];
  selectedValue.value = undefined;
  emitChange(null);
};

const emitChange = selectRow => {
  let dictData = null;
  if (selectRow != null) {
    if (props.multiple) {
      dictData = selectRow.map(item => {
        return {
          id: item[dialogProps.value.value],
          name: item[dialogProps.value.label],
          dictAllData: item,
        };
      });
    } else {
      dictData = {
        id: selectRow[dialogProps.value.value],
        name: selectRow[dialogProps.value.label],
        dictAllData: selectRow,
      };
    }
  }
  emit('update:modelValue', selectedValue.value);
  emit('change', selectedValue.value, selectRow, dictData);
};

const loadTableData = () => {
  if (dictInfo.value == null || props.modelValue === '' || props.modelValue == null) return;
  let dictKeys = Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue];
  if (dictKeys.length === 0) return;
  let params = {
    dictId: dictInfo.value.dictId,
    dictKeys: dictKeys,
  };
  OnlineOperationController.listTableDictByIds(params)
    .then(res => {
      if (res.data.length > 0) {
        res.data.forEach(item => {
          if (item[dictInfo.value.keyColumnName] != null) {
            item[dictInfo.value.keyColumnName] = item[dictInfo.value.keyColumnName].toString();
          }
        });
        selectedItems.value = res.data;
        selectedValue.value = props.modelValue;
      }
    })
    .catch(e => {
      console.error('Error loading table data:', e);
    });
};
watch(
  () => props.modelValue,
  newVal => {
    if (newVal != null && newVal !== '') {
      loadTableData();
    } else {
      onClear();
    }
  },
  { immediate: true },
);
</script>

<style scoped>
.dict-select :deep(.data-select-popper) {
  display: none;
}

.dict-select ::v-deep .el-dialog__header {
  height: 42px;
  line-height: 42px;
  padding: 0px 20px;
  background-color: #f8f8f8;
}
.dict-select ::v-deep .el-dialog__title {
  color: #333;
  font-size: 14px;
}
.dict-select ::v-deep .el-dialog__headerbtn {
  top: 12px;
}
.dict-select ::v-deep .el-dialog__body {
  padding: 25px;
}
</style>
